using System;
using dnAnalytics.Math;
using NUnit.Framework;

namespace dnAnalytics.Tests
{
    public static class TestHelper
    {
        public static void TestSignificantDigits(double expected, double approx, int digits)
        {
            //if they are equal, no reason to test.
            if (expected == approx)
            {
                return;
            }

            //no reason to test if both expected and approx are both NaN/Infinity
            if( double.IsNaN(expected)&& double.IsNaN(approx))
            {
                return;
            }
            if (double.IsInfinity(expected) && double.IsInfinity(approx))
            {
                return;
            }

            //log relative error
            double lre;
            if (expected == 0)
            {
                lre = -System.Math.Log10(System.Math.Abs(approx));
            }
            else
            {
                double factor = System.Math.Abs(approx/expected);

                //lre is only useful if expected and approx are  "close"
                if (factor > 2 || factor < .5)
                {
                    lre = 0;
                }
                else
                {
                    lre = -System.Math.Log10(System.Math.Abs(approx - expected)/System.Math.Abs(expected));
                }
            }
            Assert.IsFalse(double.IsNaN(lre));
            Assert.IsFalse(double.IsInfinity(lre));

            //for debuging failed tests.
            if (lre < digits)
            {
                Console.WriteLine("expected: {0}, approx: {1}, lre: {2}", expected, approx, lre);
            }

            Assert.That(lre, Is.AtLeast(digits));
        }


        public static void TestSignificantDigits(Complex expected, Complex approx, int digits)
        {
            TestSignificantDigits(expected.Real, approx.Real, digits);
            TestSignificantDigits(expected.Imaginary, approx.Imaginary, digits);
        }
    }
}